package com.btcode.netty.server.handler;

import com.btcode.common.MyLog;
import com.btcode.log.ILog;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 1.用于消息的拆包粘包（必须实现自己的decode方法），准确定位完整的消息，可参照@com.btcode.netty.server.handler.decode及hrt包内的实现类的使用说明
 * 3.快速的消息解码处理工具类，如字符串协议和字节协议
 */
public abstract class AbstractHrtDecoder extends ByteToMessageDecoder {
    protected final ILog log = MyLog.getInstance().getLogger(AbstractHrtDecoder.class);

    /**
     * 如果消息本身没有ID 唯一的方法实现，那么将不执行会话管理相关功能
     */
    public abstract String getMnFromChannel(ChannelHandlerContext ctx, ByteBuf msgDecodeOut);

    private final static boolean[] SCCAUNC = new boolean[]{false, false};

    /**
     * 根据的getMnFromChannel的一致性，决定是否对ID冲突连接进行处理，默认不处理
     * 冲突时是否使用新的channel，否则断开已存在的id连接
     *
     * @return
     */
    public boolean[] shouldCheckConflictAndUseNewConn() {
        return SCCAUNC;
    }

    /**
     * 截取字符串消息 parmName + "=(.+?);";
     *
     * @param regex
     * @param text
     * @return
     */
    public static String getRegSplitValue(String regex, String text) {
        Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(text);
        while (matcher.find()) {
            return matcher.group(1);
        }
        return null;
    }

    /**
     * 212相关字符串消息快速解码
     *
     * @param msgDecodeOut ByteBuf
     * @return
     */
    public static String getByteBufString(ByteBuf msgDecodeOut) {
        return msgDecodeOut.toString(Charset.defaultCharset());
    }

    /**
     * 供水相关字节消息快速解码
     *
     * @param msgDecodeOut ByteBuf
     * @return
     */
    public static String getByteBufHexStr(ByteBuf msgDecodeOut) {
        return bytes2Hex(msgDecodeOut.toString(Charset.defaultCharset()).getBytes());
    }

    /**
     * 供水相关字节消息快速解码
     *
     * @param msgDecodeOut ByteBuf
     * @return
     */
    public static byte[] getByteBufBytes(ByteBuf msgDecodeOut) {
        return msgDecodeOut.toString(Charset.defaultCharset()).getBytes();
    }

    public static String bytes2Hex(byte[] bytes) {
        if (bytes == null || bytes.length == 0) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        for (byte aByte : bytes) {
            sb.append(String.format("%02X", aByte));
        }
        return sb.toString().trim();
    }

    public static byte[] hexToBytes(String hex) {
        int m = 0, n = 0;
        int byteLen = hex.length() / 2; // 每两个字符描述一个字节
        byte[] ret = new byte[byteLen];
        for (int i = 0; i < byteLen; i++) {
            m = i * 2 + 1;
            n = m + 1;
            int intVal = Integer.decode("0x" + hex.substring(i * 2, m) + hex.substring(m, n));
            ret[i] = (byte) intVal;
        }
        return ret;
    }

    public static byte[] int2Bytes(int i) {
        byte[] arr = new byte[4];
        arr[0] = (byte) i;
        arr[1] = (byte) (i >> 8);
        arr[2] = (byte) (i >> 16);
        arr[3] = (byte) (i >> 24);
        return arr;
    }

    /**
     * @param bytes 数字量
     * @return
     */
    public static int bytes2Int(byte[] bytes) {
        try {
            return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getInt();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * @param bytes 数字量
     * @return
     */
    public static long bytes2Long(byte[] bytes) {
        try {
            return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getLong();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }
}
